import Vue,{PropOptions,VNode,CreateElement,VNodeChildren,PropType,VueConstructor} from 'vue';
import mixins from 'vue-typed-mixins';
import {Align,FieldGetter,Formatter,PlainObject,Sorter,SizeObj,LoadStatus} from '../../../../types';
import {QResizeObserver,QSpinner,event,Platform} from 'quasar';
import 'tippy.js/animations/perspective.css';
import Icon from '../icon';
import BothScrollArea from '../both-scroll-area';
import Checkbox from '../checkbox';
import Radio from '../radio';
import Tippy from '../tippy';
import {getCalcColumnWidthFn,loopTree,WidthDescribe,storageSet,storageGet} from '../../../util/common';
import {NO_DATA,NO_FILTER_DATA} from '../../js/pc/message';
import TreeMixin,{ComputedObj,FilterMethod,FilterType,LazyTemp,RawObj} from '../../js/pc/mixin/treeMixin';
import {MySet} from '../../../util/polyfill';
// @ts-ignore
import {throttle} from 'lodash';
const {stopAndPrevent}=event;
/**
 * fixme 列固定, 右侧固定且单元格合并后会有bug, 且不支持ie
 * todo 复选框列自定义选项
 * todo 虚拟滚动
 * todo 行固定
 * todo 列类型-拖拽行
 * todo 排序和过滤
 */
//region 定义接口
/**
 * 列类型
 */
export type ColumnType='index'|'checkbox'|'radio'|'expand'|'tree';
/**
 * 固定列类型
 */
export type FixedType='left'|'right';
/**
 * 列描述对象
 * ---通用属性---
 * @property {string} name					唯一键
 * @property {string} [label]				列名称
 * @property {ColumnObj} [children]			列头分组
 * @property {string} [headClasses]			列头类名
 * @property {PlainObject} [headStyle]		列头样式
 * @property {string} [headSlot]			列头插槽
 * ---末级属性---
 * @property {boolean} [hide]				隐藏
 * @property {boolean} [configurable]		可配置显示隐藏
 * @property {WidthDescribe} [width]		列宽度
 * @property {string|FieldGetter} [field]	显示字段
 * @property {Formatter} [format]			格式化
 * @property {Align} [align]				对齐方式
 * @property {boolean} [sortable]			可排序
 * @property {Sorter} [sort]				排序方法
 * @property {boolean} [resizable]			可拖拽列宽
 * @property {string} [slot]				单元格插槽
 * @property {ColumnType} [type]			列类型
 * @property {string|FieldGetter} [classes]	列类名
 * @property {PlainObject|FieldGetter} [style]	列样式
 * @property {FieldGetter} [mergeMethod]		合并单元格
 * @property {Function} [headCheckBeforeChange] type为checkbox时, 表头的切换前置处理器
 * @property {Function} [checkBeforeChange]     type为checkbox时, 表体的切换前置处理器
 * ---根级属性---
 * @property {FixedType} [fixed]			固定列
 * ---统计属性---
 * @property {string|FieldGetter} [summaryField]	统计的显示字段(没有则使用field)
 * @property {Formatter} [summaryFormat]			统计的格式化(没有则使用format)
 * @property {Align} [summaryAlign]					统计的对齐方式(没有则使用align)
 * @property {string} [summarySlot]					统计的单元格插槽
 * @property {string|FieldGetter} [summaryClasses]		统计的列类名
 * @property {PlainObject|FieldGetter} [summaryStyle]	统计的列样式
 * @property {FieldGetter} [summaryMergeMethod]			统计的合并单元格
 */
export interface ColumnObj{}
/**
 * 原始对象
 * @property {boolean} [_selectable]		可选中
 * @property {boolean} [_treeTickable]		树可勾选
 * @property {boolean} [_listTickable]		列表可勾选
 * @property {boolean} [_treeExpandable]	树可展开
 * @property {boolean} [_listExpandable]	是否是可展开行
 * @property {boolean} [_treeNoTick]		树没有勾选框
 * @property {TickStrategy} [_tickStrategy]	勾选策略
 * @property {boolean} [_treeLazy]			树懒加载
 * @property {boolean} [_expandLazy]		可展开行懒加载
 */
export interface ListRawObj extends RawObj{
	readonly _listTickable?:boolean,
	readonly _listExpandable?:boolean,
	readonly _expandLazy?:boolean,
}
/**
 * 行信息
 * @property {ListRawObj} row		原始行信息
 * @property {number} index			行索引
 * @property {ComputedObj} [meta]	计算后的行信息(树模式才有)
 */
export interface RowScope{
	row:ListRawObj,
	index:number,
	meta?:ComputedObj,
}
/**
 * 单元格信息
 * @property {ListRawObj} row		原始行信息
 * @property {number} index			行索引
 * @property {ColumnObj} column		列信息
 * @property {number} columnIndex	列索引
 * @property {ComputedObj} [meta]	计算后的行信息(树模式才有)
 */
export interface CellScope extends RowScope{
	column:ColumnObj,
	columnIndex:number,
}
/**
 * 合并单元格的信息
 * @property {number} rowspan	跨行
 * @property {number} colspan	跨列
 */
export interface MergeInfo{
	rowspan:number,
	colspan:number,
}
export interface ColumnObj{
	name:string,
	label?:string,
	children?:Array<ColumnObj>,
	headClasses?:string,
	headStyle?:PlainObject,
	headSlot?:string,
	hide?:boolean,
	configurable?:boolean,
	width?:WidthDescribe,
	field?:string|FieldGetter<CellScope>,
	format?:Formatter<any>,
	align?:Align,
	sortable?:boolean,
	sort?:Sorter<string>,
	resizable?:boolean,
	slot?:string,
	type?:ColumnType,
	classes?:string|FieldGetter<CellScope>,
	style?:PlainObject|FieldGetter<CellScope,PlainObject>,
	mergeMethod?:FieldGetter<CellScope,MergeInfo|undefined>,
	fixed?:FixedType,
	summaryField?:string|FieldGetter<CellScope>,
	summaryFormat?:Formatter<any>,
	summaryAlign?:Align,
	summarySlot?:string,
	summaryClasses?:string|FieldGetter<CellScope>,
	summaryStyle?:PlainObject|FieldGetter<CellScope,PlainObject>,
	summaryMergeMethod?:FieldGetter<CellScope,MergeInfo|undefined>,
	headCheckBeforeChange?:(data:'indeterminate' | boolean) => void | boolean | Promise<void | boolean>;
	checkBeforeChange?:(data:{active:boolean;cellScope:CellScope;}) => void | boolean | Promise<void | boolean>;
}
/**
 * 计算后的列描述对象
 * @property {ColumnObj}	column 				列描述对象
 * @property {FixedType}	[fixed]				固定列的类型
 * @property {boolean}		[offset]			固定距离
 * @property {boolean}		[edge]				是否是固定列边界(显示阴影)
 * @property {boolean}		[last]				是否是最后一列(不显示边框)
 * @property {number}		[colspan]			跨列
 * @property {Array<HeadCellObj>} [children]	子列头
 */
export interface HeadCellObj{
	readonly column:ColumnObj,
	fixed?:FixedType,
	offset?:number,
	edge?:boolean,
	last?:boolean,
	colspan:number,
	children?:Array<HeadCellObj>,
}
/**
 * 获取单元格显示值的方法
 * @param {CellScope} scope	单元格信息
 * @return {string}			单元格显示值
 */
export interface GetCellValue{
	(scope:CellScope,field?:string|FieldGetter<CellScope>,format?:Formatter<any>):string
}
/**
 * 过滤方法的参数
 * @property {ListRawObj} row				原始行信息
 * @property {number} index					行索引
 * @property {FilterType} filter			当前过滤值
 * @property {Array<HeadCellObj>} columns		列信息
 * @property {GetCellValue} getCellValue	获取单元格显示值的方法
 * @property {ComputedObj} [meta]			计算后的行信息(树模式才有)
 */
export interface FilterMethodParam{
	row:ListRawObj,
	index:number,
	filter:FilterType,
	columns:Array<HeadCellObj>,
	getCellValue:GetCellValue,
	meta?:ComputedObj,
}
/**
 * 定义非响应数据
 * @property {number} clickTimeout
 */
interface TableVue extends Vue{
	clickTimeout?:number,
	columnDragStart:string,
	// eslint-disable-next-line camelcase
	$_lms_mousemove2:(this:Window,ev:MouseEvent) => any,
	dragColumnIndex:number,
	dragColumnWidth:number,
	dragColumnStart:number,
	dragColumnOrigin:number,
}
//endregion
/**
 * 表格
 * @author 唐国雄
 * @date 2021/5/29
 * 属性----------------------
 * :full-height				100%高度,只有横向滚动条
 * :data					数据列表, Array<ListRawObj>
 * :columns					列信息, Array<ColumnObj>
 * :obj-key					主键, string | FieldGetter<RawObj>
 * :loading					加载状态, boolean
 * :border					纵向边框, boolean
 * :hoverable				悬停高亮, boolean
 * :no-data-label			无数据提示, string
 * :no-results-label		无过滤结果提示, string
 * :children-key			子节点属性, string
 * :filter					过滤值, string | FilterObj<FilterMethodParam>
 * :filter-method			过滤方法, FilterMethod<FilterMethodParam>
 * :tick-strategy			勾选策略(必须设置children-key), TickStrategy
 * :accordion				同一级只展开一个(必须设置children-key), boolean
 * :highlightable			是否能点击高亮, boolean
 * :highlighted				高亮的行(支持sync), ListRawObj
 * :selectable				是否能选中, boolean
 * :selected				选中的行(支持sync), ListRawObj
 * :tree-ticked				勾选的行(支持sync), MySet<ListRawObj>
 * :list-ticked				勾选的行,设置了type为'checkbox'(支持sync), MySet<ListRawObj>
 * :tree-expanded			展开的行(支持sync)(必须设置children-key), MySet<ListRawObj>
 * :list-expanded			展开的可展开行(支持sync), MySet<ListRawObj>
 * :emit-all-ticked			发射所有勾选或者半勾选的节点, boolean
 * :no-leaf-ticking			没有末级勾选策略(用于优化大数据), boolean
 * :row-class				设置每一行的class, FieldGetter<RowScope>
 * :row-style				设置每一行的style, FieldGetter<RowScope,PlainObject>
 * :merge-method			合并单元格, FieldGetter<CellScope,MergeInfo|undefined>
 * :summary-data			统计数据, Array<PlainObject>
 * :summary-merge-method	统计的合并单元格, FieldGetter<CellScope,MergeInfo|undefined>
 * :custom-columns			自定义显示列, boolean
 * :drag-column				拖拽列, boolean
 * :cache-key				缓存键, string
 * :configurable-disable	可配置列,切换隐藏显示是否禁用
 * :dblclick-time			双击事件间隔时间, number
 * 事件----------------------
 * @update:highlighted		高亮的行, ListRawObj
 * @update:selected			选中的行, ListRawObj
 * @update:tree-ticked		勾选的行, MySet<ListRawObj>
 * @update:list-ticked		勾选的行,设置了type为'checkbox', MySet<ListRawObj>
 * @update:tree-expanded	展开的行, MySet<ListRawObj>
 * @update:list-expanded	展开的可展开行, MySet<ListRawObj>
 * @all-ticked				所有勾选或者半勾选的节点, Array<ListRawObj>
 * @tree-lazy-load			树开始懒加载, {meta:ComputedObj, done:(Array<ListRawObj>) => void, fail:() => void}
 * @expand-lazy-load		可展开行开始懒加载, {row:ListRawObj, done:() => void, fail:() => void}
 * @click					单击事件, CellScope
 * @dblclick				双击事件, CellScope
 * @tree-ticked				点击可勾选的勾选框, {meta:ComputedObj, state:boolean}
 * @body-size				实际标体的大小, {width:number,height:number}
 * @v-scroll				表体纵向滚动事件
 * @row-mouseenter			行移入
 * @row-mouseleave			行移出
 * 方法----------------------
 * setExpandedUnlimited(opts:Array<Operation>)		设置行的展开状态(无视限制)
 * setTickedUnlimited(opts:Array<Operation>)		设置行的勾选状态(无视限制)
 * setExpanded(key:string,state:boolean)			树模式下, 设置行的展开状态(带校验), Promise<void>
 * setExpandeds(keys:Array<string>,state:boolean)	树模式下, 批量设置行的展开状态(带校验), Promise<void>
 * setMatchesExpanded(state:boolean)				树模式下, 设置所有匹配节点的展开状态(带校验), Promise<void>
 * expandedToNode(key:string)						展开到当前节点(带校验), Promise<void>
 * setTicked(key:string,state:boolean)				树模式下, 设置行的勾选状态(带校验)
 * setTickeds(keys:Array<string>,state:boolean)		树模式下, 批量设置行的勾选状态(带校验)
 * getMeta(key:string):ComputedObj|undefined		树模式下, 获取行的所有状态信息
 * getMetas():Array<ComputedObj>|undefined			树模式下, 获取所有行的所有状态信息
 * 插槽----------------------
 * #loading					加载中, {height:number}
 * #no-data					无数据提示, {height:number}
 * #no-results				无过滤结果提示, {height:number}
 * #body-cell				单元格, {value:string} & CellScope
 * #body-cell-[name]		slot指定的单元格, {value:string} & CellScope
 * #head-cell				列头单元格, {column:ColumnObj}
 * #head-cell-[name]		headSlot指定的列头单元格, {column:ColumnObj}
 * #summary-cell			统计单元格, {value:string} & CellScope
 * #summary-cell-[name]		summarySlot指定的统计单元格, {value:string} & CellScope
 * #expanded				展开行的内容, RowScope
 * #custom-column           自定义显示列
 */
export default mixins(TreeMixin,{} as VueConstructor<TableVue>).extend({
	name:'Table',
	props:{
		//100%高度,只有横向滚动条
		fullHeight:Boolean,
		//定义列
		columns:{
			type:Array,
			required:true,
		} as PropOptions<Array<ColumnObj>>,
		//加载状态
		loading:Boolean,
		//是否带边框
		border:Boolean,
		//悬停高亮
		hoverable:Boolean,
		//没有数据时提示
		noDataLabel:{
			type:String,
			default:NO_DATA,
		},
		//没有过滤结果时提示
		noResultsLabel:{
			type:String,
			default:NO_FILTER_DATA,
		},
		//过滤方法
		filterMethod:{
			type:Function,
			default({row,index,filter,columns,getCellValue,meta}:FilterMethodParam){
				return columns.some(({column},columnIndex) => {
					const value=getCellValue({row,index,column,columnIndex,meta});
					return typeof filter==='string'?value.indexOf(filter)>-1:filter.test(value);
				});
			}
		} as PropOptions<FilterMethod<FilterMethodParam>>,
		//是否能点击高亮
		highlightable:Boolean,
		//高亮的行
		highlighted:{} as PropOptions<ListRawObj>,
		//设置每一行的class
		rowClass:Function as PropType<FieldGetter<RowScope>>,
		//设置每一行的style
		rowStyle:Function as PropType<FieldGetter<RowScope,PlainObject>>,
		//合并单元格
		mergeMethod:Function as PropType<FieldGetter<CellScope,MergeInfo|undefined>>,
		//统计数据
		summaryData:Array as PropOptions<Array<PlainObject>>,
		//统计的合并单元格
		summaryMergeMethod:Function as PropType<FieldGetter<CellScope,MergeInfo|undefined>>,
		//勾选的行,设置了type为'checkbox'(支持sync)
		listTicked:MySet as PropType<MySet<ListRawObj>>,
		//展开的可展开行(支持sync)
		listExpanded:MySet as PropType<MySet<ListRawObj>>,
		//自定义显示列
		customColumns:{
			type:Boolean,
			default:true,
		},
		//拖拽列
		dragColumn:{
			type:Boolean,
			default:true,
		},
		//缓存键
		cacheKey:String,
		configurableDisable:Function as PropType<(show:MySet<string>,col:ColumnObj) => boolean>,
		//双击事件间隔时间
		dblclickTime:{
			type:Number,
			default:400,
		},
	},
	data(){
		return {
			//表格宽度
			width:0,
			//表格高度
			bodyHeight:0,
			//高亮的行
			innerHighlighted:(this.highlighted||null) as ListRawObj|null,
			//勾选的行,设置了type为'checkbox'
			innerListTicked:(this.listTicked||new MySet<ListRawObj>()) as MySet<ListRawObj>,
			//展开的可展开行
			innerListExpanded:(this.listExpanded||new MySet<ListRawObj>()) as MySet<ListRawObj>,
			//可展开行懒加载缓存
			expandLazy:{} as LazyTemp,
			//横向滚动距离
			scrollLeft:0,
			//显示的列
			showColumns:new MySet<string>(),
			//列顺序
			sortedColumns:[] as Array<string>,
			//列宽
			columnsWidth:{} as {[key:string]:number},
			//列宽改变标识
			resizeLine:null as number|null,
			//正在改变固定列的列宽
			dragColumnFixed:false as false|FixedType,
			//排序的列
			sortColumn:null as ColumnObj|null,
			//是否升序
			sortAsc:true,
			appendTo:null,
			cacheKeyToSet:false,
		};
	},
	computed:{
		//region 类名
		classes():string{
			return 'lexmis-Table'+
				(this.border?' lexmis--border':this.columnsInfo.multiRowColumns.length<=1?' lexmis--noHeadBorder':'')+
				(this.hoverable?' lexmis--hoverable':'');
		},
		//endregion
		//region 列数据缓存
		columnsCache():{[name:string]:ColumnObj}{
			const columns=this.columns;
			const columnsCache:{[name:string]:ColumnObj}={};
			for(let i=0;i<columns.length;++i){
				const column=columns[i];
				columnsCache[column.name]=column;
			}
			return columnsCache;
		},
		//endregion
		//region 所有末级列头
		allLastRowColumns():Array<ColumnObj>{
			const allLastRowColumns:Array<ColumnObj>=[];
			loopTree(this.columns,({node}) => {
				if(!node.children){
					allLastRowColumns.push(node);
				}
			});
			return allLastRowColumns;
		},
		//endregion
		configurableColumns():Array<ColumnObj>{
			return this.allLastRowColumns.filter((column) => {
				return column.configurable!==false;
			});
		},
		//region 真正显示的列数据
		realColumns():Array<ColumnObj>{
			const {showColumns}=this;
			const filter=(columns:Array<ColumnObj>) => {
				const result:Array<ColumnObj>=[];
				for(let i=0;i<columns.length;++i){
					const column=columns[i];
					if(column.children){
						const children=filter(column.children);
						if(children.length){
							result.push({
								...column,
								children,
							});
						}
					}else if(showColumns.has(column.name)){
						result.push(column);
					}
				}
				return result;
			};
			const {columnsCache,sortedColumns}=this;
			return filter(
				sortedColumns.map((name) => {
					return columnsCache[name];
				}).filter((column) => column!=null)
			);
		},
		//endregion
		//region 列信息
		columnsInfo():{lastRowColumns:Array<HeadCellObj>,multiRowColumns:HeadCellObj[][]}{
			const lastRowColumns:Array<HeadCellObj>=[];
			const multiRowColumns:HeadCellObj[][]=[];
			function buildList(columns:Array<ColumnObj>,deep=0){
				if(!multiRowColumns[deep]){
					multiRowColumns[deep]=[];
				}
				const singleRowColumns=[];
				for(let i=0;i<columns.length;++i){
					const column=columns[i];
					const headCell:HeadCellObj={
						column,
						colspan:1,
					};
					singleRowColumns.push(headCell);
					if(column.children){
						headCell.children=buildList(column.children,deep+1);
						headCell.colspan=headCell.children.reduce((a,b) => {
							return a+b.colspan;
						},0);
					}else{
						lastRowColumns.push(headCell);
					}
				}
				multiRowColumns[deep]=multiRowColumns[deep].concat(singleRowColumns);
				return singleRowColumns;
			}
			//根据固定列重新排序
			const columns=this.realColumns;
			const left:Array<ColumnObj>=[];
			const normal:Array<ColumnObj>=[];
			const right:Array<ColumnObj>=[];
			if(!Platform.is.ie){
				for(let i=0;i<columns.length;++i){
					if(columns[i].fixed==='left'){
						left.push(columns[i]);
					}else if(columns[i].fixed==='right'){
						right.push(columns[i]);
					}else{
						normal.push(columns[i]);
					}
				}
				buildList(left.concat(normal).concat(right));
			}else{
				buildList(columns);
			}
			const firstRowColumns=multiRowColumns[0];
			let OffsetLeft=0;
			let OffsetRight=0;
			if(left.length>0){
				const leftFixedColumns=firstRowColumns.slice(0,left.length);
				for(let i=0;i<leftFixedColumns.length;++i){
					const headCell=leftFixedColumns[i];
					setFixed(headCell,'left',OffsetLeft);
					OffsetLeft+=headCell.colspan;
				}
				setEdge(leftFixedColumns[leftFixedColumns.length-1],{edge:true},false);
			}
			if(right.length>0){
				const rightFixedColumns=firstRowColumns.slice(-right.length);
				for(let i=rightFixedColumns.length-1;i>=0;--i){
					const headCell=rightFixedColumns[i];
					setFixed(headCell,'right',OffsetRight);
					OffsetRight+=headCell.colspan;
				}
				setEdge(rightFixedColumns[0],{edge:true},true);
			}
			if(firstRowColumns.length>0){
				setEdge(firstRowColumns[firstRowColumns.length-1],{last:true},false);
			}
			function setFixed(headCell:HeadCellObj,fixed:FixedType,offset:number){
				headCell.fixed=fixed;
				headCell.offset=offset;
				const children=headCell.children;
				if(children){
					if(fixed==='left'){
						for(let i=0;i<children.length;++i){
							setFixed(children[i],fixed,offset);
							offset+=children[i].colspan;
						}
					}else{
						for(let i=children.length-1;i>=0;--i){
							setFixed(children[i],fixed,offset);
							offset+=children[i].colspan;
						}
					}
				}
			}
			function setEdge(headCell:HeadCellObj,extend:PlainObject,first:boolean){
				if(first){
					do{
						Object.assign(headCell,extend);
					}while(headCell.children&&(headCell=headCell.children[0]));
				}else{
					do{
						Object.assign(headCell,extend);
					}while(headCell.children&&(headCell=headCell.children[headCell.children.length-1]));
				}
			}
			return {
				lastRowColumns,
				multiRowColumns,
			};
		},
		//endregion
		//region 列宽计算函数
		calcColumnWidthFn():(width:number)=>Array<number>{
			const columnsWidth=this.columnsWidth;
			return getCalcColumnWidthFn(this.columnsInfo.lastRowColumns.map(({column}) => {
				return columnsWidth[column.name]??column.width;
			}));
		},
		//endregion
		//region 实际列宽数组
		colWidth():Array<number>{
			return this.calcColumnWidthFn(this.width);
		},
		//endregion
		//region 表格内总宽
		innerWidth():number{
			return this.colWidth.reduce((a,b) => {
				return a+b;
			},0);
		},
		//endregion
		//region 列表模式, 显示的行
		listRows():Array<ListRawObj>{
			const {curFilter,data,curFilterMethod,columnsInfo:{lastRowColumns},getCellValue}=this;
			if(curFilter){
				return data.filter((row,index) => {
					return curFilterMethod({
						row,
						index,
						filter:curFilter,
						columns:lastRowColumns,
						getCellValue,
					} as FilterMethodParam);
				});
			}
			return data;
		},
		//endregion
		//region 列表模式, 显示顺序
		showListRows():Array<ListRawObj>{
			let listRows=this.listRows;
			const {sortColumn,sortAsc,columnsInfo:{lastRowColumns},getCellValue}=this;
			if(sortColumn){
				const columnIndex=lastRowColumns.findIndex(({column:{name}}) => {
					return name===sortColumn.name;
				});
				const sortMethod:Sorter<string>=sortColumn.sort||((a,b) => {
					if(a===b){
						return 0;
					}else if(a<b){
						return -1;
					}else{
						return 1;
					}
				});
				listRows=listRows.map((row,index) => {
					return {row,index};
				}).sort((ele1,ele2) => {
					const val1=getCellValue({
						...ele1,
						column:sortColumn,
						columnIndex
					});
					const val2=getCellValue({
						...ele2,
						column:sortColumn,
						columnIndex
					});
					return sortMethod(val1,val2)*(sortAsc?1:-1);
				}).map(({row}) => {
					return row;
				});
			}
			return listRows;
		},
		//endregion
		//region 列表模式, 可勾选的行
		tickableListRows():Array<ListRawObj>{
			return this.listRows.filter((row) => {
				return row._listTickable!==false;
			});
		},
		//endregion
		//region 传给Tippy组件的属性
		tippyOptions():PlainObject{
			return {
				advanced:true,
				head:false,
				width:0,
				appendTo:this.appendTo,
				'tippy-options':{
					arrow:false,
					placement:'bottom-start',
					duration:[300,300],
					animation:'perspective',
					offset:[0,5],
					theme:'lexmis-widget',
				}
			};
		},
		//endregion
		//region 是否有显示的可变列宽列
		resizable():boolean{
			return this.columnsInfo.lastRowColumns.some(({column:{resizable}}) => {
				return resizable!==false;
			});
		},
		//endregion
	},
	watch:{
		highlighted(val){
			this.innerHighlighted=val;
		},
		listTicked(val){
			this.innerListTicked=val;
		},
		listExpanded(val){
			this.innerListExpanded=val;
		},
	},
	created(){
		this.$_lms_mousemove2=throttle(this.$_lms_mousemove,16,{trailing:false});
		this.$on('reset',(key:string) => {
			this.expandLazy={};
		});
	},
	mounted(){
		this.$nextTick(function(){
			// @ts-ignore
			this.appendTo=this.$el;
		});
		//region 监听并修改滚动条位置
		this.$watch(function(){
			return this.innerWidth-this.width;
		},function(val){
			if(val<0){
				val=0;
			}
			if(val<this.scrollLeft){
				this.scrollLeft=val;
				const {headContainer,summaryContainer}=this.$refs;
				(headContainer as HTMLElement).scrollLeft=val;
				if(summaryContainer){
					(summaryContainer as HTMLElement).scrollLeft=val;
				}
			}
		});
		//endregion
		//region 读取缓存数据
		let noCache=true;
		this.$watch('cacheKey',function(cacheKey,old){
			if(cacheKey){
				const val=storageGet('table-cache:'+cacheKey);
				if(val){
					const columns=this.columns;
					const {original=[],showColumns=[],sortedColumns=[],columnsWidth={}}=val;
					if(original.length===columns.length&&columns.every(({name},index) => {
						return name===original[index];
					})){
						noCache=false;
						this.cacheKeyToSet=true;
						this.showColumns=new MySet<string>(showColumns);
						this.sortedColumns=sortedColumns;
						this.columnsWidth=columnsWidth;
					}
				}
			}
		},{immediate:true});
		//endregion
		//region 监听并修改显示的列
		this.$watch('allLastRowColumns',function(){
			if(!this.cacheKeyToSet){
				const {allLastRowColumns}=this;
				const showColumns=new MySet<string>();
				for(let i=0;i<allLastRowColumns.length;++i){
					if(!allLastRowColumns[i].hide){
						showColumns.add(allLastRowColumns[i].name);
					}
				}
				if(
					showColumns.size!==this.showColumns.size||
					this.showColumns.some((name) => {
						return !showColumns.has(name);
					})
				){
					this.showColumns=showColumns;
					this.setToCache();
				}
			}
		},{immediate:noCache});
		//endregion
		//region 监听并修改列顺序
		this.$watch('columns',function(){
			if(!this.cacheKeyToSet){
				const sortedColumns=this.columns.map((column) => {
					return column.name;
				});
				if(
					sortedColumns.length!==this.sortedColumns.length||
					this.sortedColumns.some((name,index) => {
						return name!==sortedColumns[index];
					})
				){
					this.sortedColumns=sortedColumns;
					this.setToCache();
				}
			}
		},{immediate:noCache});
		//endregion
		this.$watch('cacheKeyToSet',function(){
			if(this.cacheKeyToSet){
				this.cacheKeyToSet=false;
				noCache=true;
			}
		});
	},
	activated(){
		const {headContainer,summaryContainer}=this.$refs;
		if(this.scrollLeft!==0){
			(headContainer as HTMLElement).scrollLeft=this.scrollLeft;
			if(summaryContainer){
				(summaryContainer as HTMLElement).scrollLeft=this.scrollLeft;
			}
		}
	},
	methods:{
		//region 设置缓存
		setToCache(){
			const {cacheKey,columns,showColumns,sortedColumns,columnsWidth}=this;
			if(cacheKey){
				storageSet('table-cache:'+cacheKey,{
					original:columns.map(({name}) => name),
					showColumns:[...showColumns],
					sortedColumns,
					columnsWidth,
				});
			}
		},
		//endregion
		//region 改变列宽
		$_lms_mousemove({clientX}:MouseEvent){
			const {dragColumnWidth,dragColumnStart,dragColumnOrigin,dragColumnFixed,width,scrollLeft}=this;
			const offset=clientX-dragColumnStart;
			let resizeLine=dragColumnOrigin+Math.max(offset*(dragColumnFixed==='right'?-1:1),40-dragColumnWidth);
			if(!dragColumnFixed&&Math.abs(width+scrollLeft-resizeLine)<10){
				resizeLine=width+scrollLeft;
			}
			this.resizeLine=resizeLine;
		},
		$_lms_mouseup(){
			const {colWidth,columnsInfo:{lastRowColumns},dragColumnOrigin,dragColumnIndex,resizeLine}=this;
			const columnsWidth=Object.assign({},this.columnsWidth);
			for(let i=0;i<lastRowColumns.length;++i){
				const name=lastRowColumns[i].column.name;
				columnsWidth[name]=colWidth[i];
				if(dragColumnIndex===i){
					columnsWidth[name]+=(resizeLine as number)-dragColumnOrigin;
				}
			}
			this.columnsWidth=columnsWidth;
			this.resizeLine=null;
			// @ts-ignore
			window.removeEventListener('mousemove',this.$_lms_mousemove2,{passive:true});
			// @ts-ignore
			window.removeEventListener('mouseup',this.$_lms_mouseup,{passive:true});
			this.setToCache();
		},
		//endregion
		//region 树模式, 获取过滤方法的参数
		$_lexmis_getFilterMethodParam(meta:ComputedObj):FilterMethodParam{
			return {
				row:meta.rawObj,
				index:meta.index,
				filter:this.curFilter,
				columns:this.columnsInfo.lastRowColumns,
				getCellValue:this.getCellValue,
				meta,
			};
		},
		//endregion
		//region 列头的渲染
		$_lexmis_renderHead(h:CreateElement){
			return this.columnsInfo.multiRowColumns.map((singleRowColumns,rowIndex,multiRowColumns) => {
				return h('tr',{
					key:rowIndex
				},
				singleRowColumns.map((
					{
						column,
						fixed,
						offset,
						edge,
						last,
						children,
						colspan,
					},
					index
				) => {
					let {name,headSlot,headClasses,headStyle,type,resizable,sortable,headCheckBeforeChange}=column;
					let show;
					if(this.childrenKey||(type&&type!=='tree')){
						sortable=false;
					}
					if(type==='checkbox'){
						const {data,innerListTicked,tickableListRows}=this;
						let select=0;
						for(let i=0;i<data.length;++i){
							if(innerListTicked.has(data[i])){
								++select;
							}
						}
						show=[
							h(Checkbox,{
								props:{
									value:select&&select===data.length
										?true
										:select===0
											?false
											:this.$baseui_theme==='fk'
												?false
												:null,
									disable:tickableListRows.length===0,
									beforeChange:headCheckBeforeChange,
								},
								on:{
									input:() => {
										if(tickableListRows.every((row) => innerListTicked.has(row))){
											innerListTicked.deleteAll(tickableListRows);
										}else{
											innerListTicked.addAll(tickableListRows);
										}
										if(this.listTicked!==undefined){
											this.$emit('update:list-ticked',innerListTicked);
										}
									}
								}
							})
						];
					}else{
						const cell=(headSlot&&this.$scopedSlots[`head-cell-${headSlot}`])||this.$scopedSlots['head-cell'];
						if(cell){
							show=cell({column});
						}else{
							show=column.label;
						}
					}
					headClasses||='';
					if(last){
						headClasses+=' lexmis--last';
					}
					const draggable:PlainObject={};
					let fixedOffset=0;
					if(fixed){
						headClasses+=` lexmis--sticky lexmis--${fixed}`+(edge?' lexmis--edge':'');
						const fixedStyle:PlainObject={};
						if(fixed==='left'){
							fixedOffset=this.colWidth.slice(0,offset).reduce((a,b) => a+b,1);
							fixedStyle.left=fixedOffset+'px';
						}else{
							fixedOffset=this.colWidth.slice(this.colWidth.length-offset!).reduce((a,b) => a+b,0);
							fixedStyle.right=fixedOffset+'px';
						}
						headStyle=Object.assign(fixedStyle,headStyle);
					}else if(this.dragColumn&&rowIndex===0){
						draggable.domProps={draggable:true};
						draggable.on={
							dragover:(e:Event) => {
								if(this.columnDragStart!==name){
									e.preventDefault();
								}
							},
							dragstart:() => {
								this.columnDragStart=name;
							},
							drop:(e:Event) => {
								e.preventDefault();
								const {sortedColumns,columnDragStart}=this;
								const index1=sortedColumns.indexOf(columnDragStart);
								const index2=sortedColumns.indexOf(name);
								const val=sortedColumns.splice(index1,1)[0];
								sortedColumns.splice(index2,0,val);
								this.setToCache();
							},
						};
					}
					const extra:VNodeChildren=[];
					if(children==null){
						if(sortable!==false){
							const sorted=this.sortColumn===column;
							extra.push(h('div',{
								staticClass:'lms-Table_sortableContainer'+(sorted?' lms--active':''),
							},[
								h('div',{
									staticClass:'lms--up'+(sorted&&this.sortAsc?' lms--active':''),
									on:{
										click:() => {
											if(this.sortColumn===column&&this.sortAsc){
												this.sortColumn=null;
											}else{
												this.sortColumn=column;
												this.sortAsc=true;
											}
										},
									}
								}),
								h('div',{
									staticClass:'lms--down'+(sorted&&!this.sortAsc?' lms--active':''),
									on:{
										click:() => {
											if(this.sortColumn===column&&!this.sortAsc){
												this.sortColumn=null;
											}else{
												this.sortColumn=column;
												this.sortAsc=false;
											}
										},
									}
								}),
							]));
						}
						if(resizable!==false){
							extra.push(h('div',{
								staticClass:'lms-Table_resizable',
								domProps:{
									draggable:true,
								},
								on:{
									dragstart:(e:Event) => {
										e.stopPropagation();
										e.preventDefault();
									},
									mousedown:({clientX}:MouseEvent) => {
										const {colWidth,columnsInfo:{lastRowColumns}}=this;
										const index=lastRowColumns.findIndex(({column}) => name===column.name);
										this.dragColumnIndex=index;
										this.dragColumnWidth=colWidth[index];
										this.dragColumnStart=clientX;
										let dragColumnOrigin=0;
										if(fixed){
											this.dragColumnFixed=fixed;
											dragColumnOrigin=fixedOffset+this.dragColumnWidth;
										}else{
											this.dragColumnFixed=false;
											for(let i=0;i<=index;++i){
												dragColumnOrigin+=colWidth[i];
											}
										}
										this.dragColumnOrigin=dragColumnOrigin;
										this.resizeLine=dragColumnOrigin;
										window.addEventListener('mousemove',this.$_lms_mousemove2,{passive:true});
										window.addEventListener('mouseup',this.$_lms_mouseup,{passive:true});
									},
								}
							}));
						}
					}
					if(extra.length){
						show=[
							h('div',{
								staticClass:'lms-Table_wrapper',
							},[
								h('div',{
									staticClass:'lms-Table_realCell',
								},show),
								h('div',{
									staticClass:'lms-Table_extra',
								},extra)
							])
						];
					}
					return h('th',{
						staticClass:headClasses,
						staticStyle:headStyle,
						key:index,
						attrs:{
							colspan,
							rowspan:children==null?multiRowColumns.length-rowIndex:undefined,
						},
						...draggable,
					},show);
				}));
			});
		},
		//endregion
		//region 行的渲染
		$_lexmis_renderRows(h:CreateElement,row:ListRawObj,index:number,meta?:ComputedObj){
			const rowScope:RowScope={row,index,meta};
			const lastRowColumns=this.columnsInfo.lastRowColumns;
			let key:string;
			if(typeof this.objKey==='string'){
				key=row[this.objKey];
			}else{
				key=this.objKey(row);
			}
			let staticClass=this.rowClass?this.rowClass(rowScope):undefined;
			if(this.highlightable&&this.innerHighlighted===row){
				staticClass=(staticClass||'')+' lms--Highlighted';
			}
			const normalRow=h('tr',{
				key:'normal-'+key,
				staticClass,
				staticStyle:this.rowStyle?this.rowStyle(rowScope):undefined,
				on:{
					mouseenter:() => {
						this.$emit('row-mouseenter',rowScope);
					},
					mouseleave:() => {
						this.$emit('row-mouseleave',rowScope);
					},
				},
			},
			lastRowColumns.map((
				{
					column,
					fixed,
					offset,
					edge,
					last,
				},
				columnIndex
			) => {
				let {classes,style,align,mergeMethod,checkBeforeChange}=column;
				const {slot,type}=column;
				const scope:CellScope={row,index,column,columnIndex,meta};
				if(!mergeMethod){
					mergeMethod=this.mergeMethod;
				}
				const mergeInfo=mergeMethod?mergeMethod(scope):undefined;
				if(mergeInfo&&(mergeInfo.rowspan===0||mergeInfo.colspan===0)){
					return null;
				}
				if(typeof classes==='function'){
					classes=classes(scope);
				}
				if(typeof style==='function'){
					style=style(scope);
				}
				const innerStyle:PlainObject={};
				let show;
				if(type){
					if(type==='index'){
						show=index+1+'';
					}else if(type==='checkbox'){
						align='center';
						show=[
							h(Checkbox,{
								props:{
									val:row,
									value:this.innerListTicked,
									disable:row._listTickable===false,
									beforeChange:checkBeforeChange && function({active}:any){
										return checkBeforeChange && checkBeforeChange({
											cellScope:scope,
											active,
										});
									},
								},
								on:{
									input:(val:MySet<ListRawObj>) => {
										if(this.listTicked!==undefined){
											this.$emit('update:list-ticked',val);
										}
									}
								}
							})
						];
					}else if(type==='radio'){
						align='center';
						show=[
							h(Radio,{
								props:{
									val:row,
									value:this.innerSelected,
									disable:row._selectable===false||!this.selectable,
								},
								on:{
									input:(val:ListRawObj) => {
										if(this.selected!==undefined){
											this.$emit('update:selected',val);
										}else{
											this.innerSelected=val;
										}
									}
								}
							})
						];
					}else if(type==='expand'){
						align='center';
						if(row._listExpandable===false){
							show=undefined;
						}else{
							let lazy:undefined|boolean|LoadStatus=row._expandLazy;
							if(lazy&&this.expandLazy[key]){
								lazy=this.expandLazy[key];
							}
							show=[
								lazy==='loading'
									?h(QSpinner,{
										staticClass:'lexmis_tree_spinner',
									})
									:h(Icon,{
										staticClass:'lexmis_tableExpandedIcon'+
											(this.innerListExpanded.has(row)?' lexmis--expanded':''),
										props:{
											name:'arrow_forward_ios',
										},
										on:{
											click:(e:Event) => {
												stopAndPrevent(e);
												if(row._listExpandable===false){
													return;
												}
												const expand=() => {
													if(this.innerListExpanded.has(row)){
														this.innerListExpanded.delete(row);
													}else{
														this.innerListExpanded.add(row);
													}
													if(this.listExpanded!==undefined){
														this.$emit('update:tree-expanded',this.innerListExpanded);
													}
												};
												if(lazy&&lazy!=='loaded'){
													this.$set(this.expandLazy,key,'loading');
													this.$emit('expand-lazy-load',{
														index,
														row,
														done:() => {
															this.expandLazy[key]='loaded';
															this.$nextTick(function(){
																expand();
															});
														},
														fail:() => {
															this.$delete(this.expandLazy,key);
														}
													});
												}else{
													expand();
												}
											}
										}
									})
							];
						}
					}else if(type==='tree'){
						if(meta){
							align='left';
							show=this.$_lexmis_renderNodeContent(
								h,
								meta,
								this.$_lexmis_getContent('body-cell',slot,scope),
								QSpinner,
								Icon,
								Checkbox
							);
						}else{
							show=this.$_lexmis_getContent('body-cell',slot,scope);
						}
					}
				}else{
					show=this.$_lexmis_getContent('body-cell',slot,scope);
				}
				innerStyle.justifyContent=align==='center'?'center':align==='right'?'flex-end':undefined;
				classes||='';
				if(last){
					classes+=' lexmis--last';
				}
				if(fixed){
					classes+=` lexmis--sticky lexmis--${fixed}`+(edge?' lexmis--edge':'');
					const fixedStyle:PlainObject={};
					if(fixed==='left'){
						fixedStyle.left=this.colWidth.slice(0,offset).reduce((a,b) => a+b,1)+'px';
					}else{
						fixedStyle.right=this.colWidth.slice(this.colWidth.length-offset!).reduce((a,b) => a+b,0)+'px';
					}
					style=Object.assign(fixedStyle,style);
				}
				return h('td',{
					staticClass:classes,
					staticStyle:style,
					key:columnIndex,
					attrs:mergeInfo,
					on:{
						click:(e:Event) => {
							this.$_lexmis_onClick(scope,e);
						},
					}
				},[
					h('div',{
						staticClass:'lexmis_content',
						staticStyle:innerStyle,
					},show)
				]);
			}));
			const expanded=this.$scopedSlots.expanded;
			if(this.innerListExpanded.has(row)&&expanded){
				return [
					normalRow,
					h('tr',{
						staticClass:'lexmis_expandedLine',
						key:'expanded-'+key,
					},[
						h('td',{
							attrs:{
								colspan:lastRowColumns.length
							}
						},expanded(rowScope))
					])
				];
			}
			return normalRow;
		},
		//endregion
		//region 统计行的渲染
		$_lexmis_renderSummary(h:CreateElement,row:PlainObject,index:number){
			return h('tr',{
				key:index,
			},this.columnsInfo.lastRowColumns.map((
				{
					column,
					fixed,
					offset,
					edge,
					last,
				},
				columnIndex
			) => {
				let {
					summaryClasses,
					summaryStyle,
					summaryMergeMethod,
				}=column;
				const {
					summaryField,
					summaryFormat,
					summaryAlign:align,
					summarySlot,
				}=column;
				const scope:CellScope={row,index,column,columnIndex};
				if(!summaryMergeMethod){
					summaryMergeMethod=this.summaryMergeMethod;
				}
				const mergeInfo=summaryMergeMethod?summaryMergeMethod(scope):undefined;
				if(mergeInfo&&(mergeInfo.rowspan===0||mergeInfo.colspan===0)){
					return null;
				}
				if(typeof summaryClasses==='function'){
					summaryClasses=summaryClasses(scope);
				}
				if(typeof summaryStyle==='function'){
					summaryStyle=summaryStyle(scope);
				}
				const innerStyle:PlainObject={};
				innerStyle.justifyContent=align==='center'?'center':align==='right'?'flex-end':undefined;
				summaryClasses||='';
				if(last){
					summaryClasses+=' lexmis--last';
				}
				if(fixed){
					summaryClasses+=` lexmis--sticky lexmis--${fixed}`+(edge?' lexmis--edge':'');
					const fixedStyle:PlainObject={};
					if(fixed==='left'){
						fixedStyle.left=this.colWidth.slice(0,offset).reduce((a,b) => a+b,1)+'px';
					}else{
						fixedStyle.right=this.colWidth.slice(this.colWidth.length-offset!).reduce((a,b) => a+b,0)+'px';
					}
					summaryStyle=Object.assign(fixedStyle,summaryStyle);
				}
				return h('td',{
					staticClass:summaryClasses,
					staticStyle:summaryStyle,
					key:columnIndex,
					attrs:mergeInfo,
				},[
					h('div',{
						staticClass:'lexmis_content',
						staticStyle:innerStyle,
					},this.$_lexmis_getContent('summary-cell',summarySlot,scope,summaryField,summaryFormat))
				]);
			}));
		},
		//endregion
		//region 空数据渲染
		$_lexmis_renderEmptyContent(h:CreateElement,slot:string,content:VNodeChildren){
			const scopedSlot=this.$scopedSlots[slot];
			return h('div',{
				staticStyle:{
					width:this.innerWidth+'px',
					height:this.bodyHeight+'px',
				}
			},[
				h('div',{
					staticClass:'lexmis_full_content',
					staticStyle:{
						width:this.width+'px',
					}
				},
				scopedSlot
					?scopedSlot({height:this.bodyHeight})
					:content
				)
			]);
		},
		//endregion
		//region 获取单元格实际内容(考虑插槽)
		$_lexmis_getContent(
			baseSlot:string,
			slot:string|undefined,
			scope:CellScope,
			field?:string|FieldGetter<CellScope>,
			format?:Formatter<any>
		):VNodeChildren{
			const cell=(slot&&this.$scopedSlots[`${baseSlot}-${slot}`])||this.$scopedSlots[baseSlot];
			const value=this.getCellValue(scope,field,format);
			if(cell){
				return cell({
					value,
					...scope,
				});
			}else{
				return value;
			}
		},
		//endregion
		//region 获取单元格显示值
		getCellValue:function(scope,field?,format?){
			if(!field){
				field=scope.column.field;
				if(!field) return '';
			}
			let value:string;
			if(typeof field==='string'){
				value=scope.row[field];
			}else{
				value=field(scope);
			}
			if(!format){
				format=scope.column.format;
			}
			if(format){
				value=format(value);
			}
			return value+'';
		} as GetCellValue,
		//endregion
		//region 单击单元格
		$_lexmis_onClick(scope:CellScope,e:Event){
			if(this.highlightable&&this.innerHighlighted!==scope.row){
				if(this.highlighted!==undefined){
					this.$emit('update:highlighted',scope.row);
				}else{
					this.innerHighlighted=scope.row;
				}
			}
			this.$emit('click',scope,e);
			if(this.$listeners.dblclick){
				if(this.clickTimeout===undefined){
					this.clickTimeout=window.setTimeout(() => {
						this.clickTimeout=undefined;
					},this.dblclickTime);
				}else{
					window.clearTimeout(this.clickTimeout);
					this.clickTimeout=undefined;
					this.$emit('dblclick',scope,e);
				}
			}
		},
		//endregion
	},
	//region 渲染函数
	render(h):VNode{
		const colgroup=this.colWidth.map((width) => {
			return h('col',{
				attrs:{
					width,
				}
			});
		});
		const staticStyle:PlainObject={};
		if(this.resizeLine==null){
			staticStyle.display='none';
		}else{
			if(this.dragColumnFixed==='left'){
				staticStyle.left=this.resizeLine+'px';
			}else if(this.dragColumnFixed==='right'){
				staticStyle.right=this.resizeLine+'px';
			}else{
				staticStyle.left=`${this.resizeLine-this.scrollLeft}px`;
			}
		}
		const result=h('div',{
			staticClass:this.classes,
			staticStyle:{
				visibility:this.width?null:'hidden',
			},
		},[
			this.resizable
				?h('div',{
					staticClass:'lms-Table_resizableLine',
					staticStyle,
				})
				:null,
			//表头渲染
			h('div',{
				staticClass:'lexmis_head',
				ref:'headContainer',
			},[
				h('table',{
					staticStyle:{
						width:this.innerWidth+'px'
					}
				},[
					h('colgroup',colgroup),
					this.$_lexmis_renderHead(h),
				]),
				this.customColumns
					?h(Tippy,{
						ref:'Tippy',
						staticClass:'lms-Table_customColumns',
						staticStyle:{
							transform:`translateX(${this.scrollLeft}px)`,
						},
						props:this.tippyOptions,
						scopedSlots:{
							content:this.$scopedSlots['custom-column']
								?(
									() => this.$scopedSlots['custom-column']?.({
										showColumns:this.showColumns,
										configurableColumns:this.configurableColumns,
										configurableDisable:this.configurableDisable,
										tippy:this.$refs.Tippy,
										setToCache:this.setToCache,
									})
								)
								:(
									() => h('div',{
										staticClass:'lms-Table_customColumnsContent',
										on:{
											mouseleave:() => {
												// @ts-ignore
												this.$refs.Tippy.hide();
											}
										}
									},this.configurableColumns.map((column,columnIndex) => {
										return h(Checkbox,{
											props:{
												val:column.name,
												value:this.showColumns,
												label:column.label,
												disable:(this.showColumns.size===1&&this.showColumns.has(column.name))||
													(this.configurableDisable&&this.configurableDisable(this.showColumns,column)),
											},
											on:{
												input:() => {
													this.setToCache();
												}
											}
										});
									}))
								),
							default:() => h(Icon,{
								props:{
									name:'expand_more',
								}
							}),
						}
					})
					:null,
			]),
			//表体渲染
			h(BothScrollArea,{
				staticClass:'lexmis_body',
				ref:'bodyScroll',
				staticStyle:{
					height:this.fullHeight?this.bodyHeight+'px':null,
					'flex-basis':this.fullHeight?this.bodyHeight+'px':null,
				},
				on:{
					paning:(scrollLeft:number) => {
						const {headContainer,summaryContainer}=this.$refs;
						scrollLeft=Math.max(0,Math.min(this.innerWidth-this.width,scrollLeft));
						if(this.scrollLeft!==scrollLeft){
							this.scrollLeft=scrollLeft;
							(headContainer as HTMLElement).scrollLeft=scrollLeft;
							if(summaryContainer){
								(summaryContainer as HTMLElement).scrollLeft=scrollLeft;
							}
						}
						this.$emit('paning',scrollLeft);
					},
					'v-scroll':(info:any) => {
						this.$emit('v-scroll',info);
					},
					...(this.fullHeight?{
						'inner-resize':(size:SizeObj) => {
							this.bodyHeight=size.height;
							this.$emit('body-size',size);
						}
					}:{
						resize:(size:SizeObj) => {
							this.bodyHeight=size.height;
						},
						'inner-resize':(size:SizeObj) => {
							this.$emit('body-size',size);
						}
					}),
				}
			},[
				this.loading
					?this.$_lexmis_renderEmptyContent(
						h,
						'loading',
						[
							h(QSpinner,{
								staticClass:'lexmis_spinner',
							})
						]
					)
					:(
						(this.treeInfo?(this.treeInfo.computedObjs.length>0):(this.listRows.length>0))
							?h('table',{
								staticStyle:{
									width:this.innerWidth+'px',
								}
							},[
								h('colgroup',colgroup),
								this.treeInfo
									?this.treeInfo.computedObjs.map((computedObj) => {
										return this.$_lexmis_renderRows(h,computedObj.rawObj,computedObj.index,computedObj);
									})
									:this.showListRows.map((row,index) => {
										return this.$_lexmis_renderRows(h,row,index);
									}),
							])
							//不存在数据
							:this.curFilter
								?this.$_lexmis_renderEmptyContent(h,'no-results',this.noResultsLabel)
								:this.$_lexmis_renderEmptyContent(h,'no-data',this.noDataLabel)
					)
			]),
			//统计渲染
			this.summaryData&&this.summaryData.length>0
				?h('div',{
					staticClass:'lexmis_summary',
					ref:'summaryContainer',
				},[
					h('table',{
						staticStyle:{
							width:this.innerWidth+'px'
						}
					},[
						h('colgroup',colgroup),
						this.summaryData.map((row,index) => {
							return this.$_lexmis_renderSummary(h,row,index);
						})
					])
				])
				:null,
			//表格大小监听
			h(QResizeObserver,{
				props:{
					debounce:100,
				},
				on:{
					resize:(size:SizeObj) => {
						this.width=size.width;
					}
				}
			})
		]);
		return result;
	},
	//endregion
});